﻿using System;
using System.IO;
using PPJoy_dotNET;
using Microsoft.Win32.SafeHandles;
using System.ServiceProcess;

namespace DroidPad
{
    class Program: ServiceBase
    {
        //static volatile bool stop;
        //static volatile bool sending = false;
        //static object stopLock = new object();
        //static object sendingLock = new object();
        public static double RADIAN_CONVERT = Math.PI / 180;
        static private DPThread dpThread = null;
        static bool[] pressedButtons = new bool[] { false, false, false };
        static private bool JoystickAllowed = false;

        public enum spcode
        {
            OK = 0,
            IPWF = 1,
            PortWF = 2,
            UpdIntWF = 3,
            ContNumWF = 4,
        }

       public Program()
        {
            this.ServiceName = "Etilan Remote";
            this.EventLog.Log = "Application";

            // These Flags set whether or not to handle that specific

            //  type of event. Set to true if you need it, false otherwise.

            this.CanHandlePowerEvent = true;
            this.CanHandleSessionChangeEvent = true;
            this.CanPauseAndContinue = true;
            this.CanShutdown = true;
            this.CanStop = true;
        }

        /// The Main Thread: This is where your Service is Run.
        static void Main()
        {
            ServiceBase.Run(new Program());
        }

        /// Actually start thread & return status
        /// <returns>Status returned, mostly errors.</returns>
        public spcode startprog()
        {
            dpThread = new DPThread(
                JoystickAllowed,
                Properties.Settings.Default.debug,
                Properties.Settings.Default.PPNum,
                Properties.Settings.Default.UpInt
                );

            //Register events here
            dpThread.InitStatSend += new DPThread.InitStatHandler(dpThread_InitStatSend);
            dpThread.Stopped += new DPThread.StopHandler(dpThread_Stopped);

            dpThread.Start();
            return spcode.OK;
        }


        #region Callbacks

        /// Callback from thread, saying thread was stopped
        void dpThread_Stopped()
        {
            AndroidStopped();
        }

        /// Callback from thread with initial status (mode etc)
        /// <param name="mode"></param>
        void dpThread_InitStatSend(DPThread.DPMode mode)
        {
            AndroidInitStatSend(mode);
        }

        private void AndroidStopped()
        {
            dpThread = null;
        }
        private void AndroidInitStatSend(DPThread.DPMode mode)
        {

        }

        #endregion


        /// Dispose of objects that need it here.
        /// <param name="disposing">Whether
        ///    or not disposing is going on.</param>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
        }


        /// OnStart(): Put startup code here
        ///  - Start threads, get inital data, etc.
        /// <param name="args"></param>

        protected override void OnStart(string[] args)
        {
            base.OnStart(args);
            #region Check for Installations
            if (DPsf.checkPPJoy())
            {
                string DevName = "\\\\.\\PPJoyIOCTL" + Convert.ToString(Properties.Settings.Default.PPNum);
                SafeFileHandle sfh = csHandle.CreateFile(DevName, FileAccess.Write, FileShare.Write, 0, FileMode.Open, 0, IntPtr.Zero);
                if (!sfh.IsInvalid)
                {
                    JoystickAllowed = true;
                }
            }


            #endregion
            if (File.Exists(Properties.Settings.Default.logPath))
                File.Delete(Properties.Settings.Default.logPath);
            startprog();
        }

        /// OnStop(): Put your stop code here
        /// - Stop threads, set final data, etc.
        protected override void OnStop()
        {
            base.OnStop();
            if (dpThread != null) dpThread.Stop();
            //Environment.Exit(0);

        }

        /// OnPause: Put your pause code here
        /// - Pause working threads, etc.
        protected override void OnPause()
        {
            base.OnPause();
        }

        /// OnContinue(): Put your continue code here
        /// - Un-pause working threads, etc.
        protected override void OnContinue()
        {
            base.OnContinue();
        }

        /// OnShutdown(): Called when the System is shutting down
        /// - Put code here when you need special handling
        ///   of code that deals with a system shutdown, such
        ///   as saving special data before shutdown.
        protected override void OnShutdown()
        {
            base.OnShutdown();
            if (dpThread != null) dpThread.Stop();
            //Environment.Exit(0);
        }

        /// <summary>

        /// OnCustomCommand(): If you need to send a command to your

        ///   service without the need for Remoting or Sockets, use

        ///   this method to do custom methods.

        /// </summary>

        /// <param name="command">Arbitrary Integer between 128 & 256</param>

        protected override void OnCustomCommand(int command)
        {
            //  A custom command can be sent to a service by using this method:

            //#  int command = 128; //Some Arbitrary number between 128 & 256

            //#  ServiceController sc = new ServiceController("NameOfService");

            //#  sc.ExecuteCommand(command);


            base.OnCustomCommand(command);
        }

        /// <summary>

        /// OnPowerEvent(): Useful for detecting power status changes,

        ///   such as going into Suspend mode or Low Battery for laptops.

        /// </summary>

        /// <param name="powerStatus">The Power Broadcast Status

        /// (BatteryLow, Suspend, etc.)</param>

        protected override bool OnPowerEvent(PowerBroadcastStatus powerStatus)
        {
            return base.OnPowerEvent(powerStatus);
        }

        /// <summary>

        /// OnSessionChange(): To handle a change event

        ///   from a Terminal Server session.

        ///   Useful if you need to determine

        ///   when a user logs in remotely or logs off,

        ///   or when someone logs into the console.

        /// </summary>

        /// <param name="changeDescription">The Session Change

        /// Event that occured.</param>

        protected override void OnSessionChange(
                  SessionChangeDescription changeDescription)
        {
            base.OnSessionChange(changeDescription);
        }
    }
}